﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Ukagaka.Named.Ghost.SakuraScript
{
	/// <summary>
	/// コマンドを表現します
	/// </summary>
	[Serializable]
	public class Command : Element
	{
		/// <summary>
		/// マークアップを取得します
		/// </summary>
		public Markup Markup
		{
			get;
			private set;
		}

		/// <summary>
		/// パラメータ群を取得します
		/// </summary>
		public List<Parameter> Parameters
		{
			get;
			private set;
		}

		/// <summary>
		/// コマンドを表現します
		/// </summary>
		/// <param name="markup">マークアップ</param>
		public Command( string markup )
			: this( new Markup( markup ) )
		{
			// do nothing
		}

		/// <summary>
		/// コマンドを表現します
		/// </summary>
		/// <param name="markup">マークアップ</param>
		public Command( Markup markup )
			: this( markup, null )
		{
			// do nothing
		}

		/// <summary>
		/// コマンドを表現します
		/// </summary>
		/// <param name="markup">マークアップ</param>
		/// <param name="parameters">パラメータ群</param>
		public Command( string markup, params Parameter[ ] parameters )
			: this( markup, ( IEnumerable<Parameter> )parameters )
		{
			// do nothing
		}

		/// <summary>
		/// コマンドを表現します
		/// </summary>
		/// <param name="markup">マークアップ</param>
		/// <param name="parameters">パラメータ群</param>
		public Command( string markup, IEnumerable<Parameter> parameters )
			: this( new Markup( markup ), parameters )
		{
			// do nothing
		}

		/// <summary>
		/// コマンドを表現します
		/// </summary>
		/// <param name="markup">マークアップ</param>
		/// <param name="parameters">パラメータ群</param>
		public Command( Markup markup, params Parameter[ ] parameters )
			: this( markup, ( IEnumerable<Parameter> )parameters )
		{
			// do nothing
		}

		/// <summary>
		/// コマンドを表現します
		/// </summary>
		/// <param name="markup">マークアップ</param>
		/// <param name="parameters">パラメータ群</param>
		public Command( Markup markup, IEnumerable<Parameter> parameters )
		{
			Markup = markup;
			Parameters = new List<Parameter>( );

			if ( null != parameters )
			{
				Parameters.AddRange( parameters );
			}
		}

		/// <summary>
		/// コマンドを取得します
		/// </summary>
		/// <returns>コマンド</returns>
		public override string ToString( )
		{
			return string.Concat( Markup, string.Concat( Parameters ) );
		}

		/// <summary>
		/// コマンドを取得します
		/// </summary>
		/// <param name="command">コマンド</param>
		/// <returns>コマンド</returns>
		public static Command FromString( string command )
		{
			var parser = new Parser( command );

			return parser.FirstOrDefault( ) as Command;
		}
	}
}
